/* Prufer序列
* 1.Prufer编码
    将一棵无根树转化为一个序列（即Prufer序列），
    另外Prufer序列也可以反过来转化为一棵树，
    即Prufer序列和树之间是一一对应的
 
* 2.凯莱定理
    一个无向完全图有 n^(n−2)棵生成树
    证明凯莱定理->证明有多少棵不同的生成树->证明有多少种Prufer序列
    Prufer序列共有 n−2 项，其范围为 1∼n，故其种类数为 n^(n−2)

* 3.Prufer算法
    假定 n 号节点为根，找到除根外度数最小的节点，在删除该节点之前，将其父节点输出，重复该流程，直到最后只剩下两个节点，
    即Prufer序列只有 n−2 个元素，因为Prufer序列最多 n−1 个元素，而最后一个元素一定为 n，所以这个元素可以省略，
    输出的元素即为Prufer序列

* 4.树-(线性时间)->Prufer序列
    假定当前出度为 0 且编号最小的节点为 j，则输出 f[j]，
    删除 j 之后，出度为 0 的节点至多只会增加一个，即 f[j]，
    判断删除 j 之后 f[j] 的出度是否为 0，如果 f[j] 的出度为 0 且 f[j]<j 说明 f[j] 是当前出度为 0 且编号最小的节点，递归输出这样的父节点即可，
    否则说明这样的 j 只会更大，即 j 只会增加，
    这样即可线性时间内将一颗树转化为Prufer序列

* 5.Prufer序列-(线性时间)->树
    先将 n 这个节点加入到Prufer序列中，Prufer序列中某个数出现的次数即为该数在树中的儿子节点的数量，
    从 1 开始找到儿子数量为 0 且编号最小的节点 j，其父节点即为当前遍历的Prufer序列的元素，将该元素从Prufer序列中删去，
    因为删除该元素后儿子数量为 0 的节点数量至多直接增加一个，
    如果该元素的儿子数量为 0 且编号小于 j，说明当前节点即为儿子数量为 0 且编号最小的节点，递归处理即可，
    这样的 j 同样也是递增的，
    故可以在线性时间内将一个Prufer序列转化为一棵树
*/

#define DEBUG
#pragma GCC optimize("O1,O2,O3,Ofast")
#pragma GCC optimize("no-stack-protector,unroll-loops,fast-math,inline")
#pragma GCC target("avx,avx2,fma")
#pragma GCC target("sse,sse2,sse3,sse4,sse4.1,sse4.2,ssse3")

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;

const int N = 10000010, INF = 0x3f3f3f3f;

int n, m;
int fa[N]; //把n看作根节点，每个节点的父节点
int out[N]; //记录每个节点的出度
int prufer[N]; //记录Prufer编码

void Tree2Prufer() //树-(线性时间)->Prufer序列
{
    for(int i=1; i<n; i++)
    {
        cin >> fa[i]; //每个节点的父节点
        out[fa[i]]++;
    }

    for(int i=0, j=1; i<n-2; j++)
    {
        while(out[j]) j++; //第一个叶节点
        prufer[i++]=fa[j]; //输出相邻节点
        //删除当前最小叶节点后，它的父节点是编号最小的叶节点，直接输出
        while(i<n-2 && --out[prufer[i-1]] == 0 && prufer[i-1]<j) prufer[i++]=fa[prufer[i-1]];
    }
    for(int i=0; i<n-2; i++) printf("%d ", prufer[i]);
}

void Prufer2Tree() //Prufer序列-(线性时间)->树
{
    for(int i=1; i<=n-2; i++)
    {
        cin >> prufer[i];
        out[prufer[i]]++; //每个点的出度是其在Prufer编码中出现的次数
    }
    prufer[n-1]=n; //Prufer序列中最后一个数一定是n
    for(int i=1, j=1; i<n; i++, j++)
    {
        while(out[j]) j++; //第一个叶节点
        fa[j] = prufer[i]; //j的父节点就是Prufer序列
        //删除j后，j的父节点是编号最小的叶节点，继续配对父节点
        while(i<n-1 && --out[prufer[i]] == 0 && prufer[i]<j) fa[prufer[i]]=prufer[i+1], i++;
    }
    for(int i=1; i<=n-1; i++) printf("%d ", prufer[i]);
}

signed main()
{
    #ifdef DEBUG
        freopen("./in.txt","r",stdin);
    #else
        ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    #endif

    cin >> n >> m;
    if(m==1) Tree2Prufer();
    else Prufer2Tree();

    return 0;
}